from django.conf import settings
from django.db.models import Avg, Sum, Count, Max, Min, Q, F
from django.db.models import Value
from django.db.models import IntegerField as intf
from django.forms.models import model_to_dict

from rest_framework import serializers
from rest_framework.serializers import *
from rest_framework.validators import UniqueValidator, UniqueTogetherValidator  # 验证器

from iClouds.Authentication import (
    BarJWTAuthentication,
    WeChatJWTAuthentication,
    MyJWTAuthentication,
)
from iClouds.Permissions import (
    BarPermissions,
    WeChatPermissions,
    MyPermissions,
    AllPermissions,
    OR,
)
from mysqldb.models import *
from mysqldb import redis as REDIS

from .FilterSets import *


class NoneSerializer(serializers.Serializer):
    """无序列化"""

    class Meta:
        fields = "__all__"


class MiniSerializer(serializers.Serializer):
    """小序列化"""

    rid = IntegerField(help_text="角色ID")

    class Meta:
        fields = "__all__"


class WeChatMessageSerializer(serializers.Serializer):
    """微信统一模板消息"""

    phone = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="手机号码",
    )
    info = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="消息",
    )

    class Meta:
        fields = "__all__"


# class WeChatBindStaffSerializer(serializers.Serializer):
#     """绑定微信"""

#     username = RegexField(r"^1[35678]\d{9}$", help_text="手机号码，后台登录账号")
#     password = CharField(max_length=4, help_text="验证码")
#     openid = CharField(
#         allow_blank=True, allow_null=True, max_length=255, help_text="微信Openid"
#     )

#     class Meta:
#         fields = "__all__"


class WeChatLoginSerializer(serializers.Serializer):
    """微信登录"""

    code = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程",
    )

    class Meta:
        fields = "__all__"


class WeChatMobleSerializer(serializers.Serializer):
    """微信获取手机号"""

    code = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程",
    )
    openid = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="openid",
    )
    unid = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="unionid",
    )

    class Meta:
        fields = "__all__"


class WeChatStaffBindSerializer(serializers.Serializer):
    """微信手机绑定"""

    phone = RegexField(
        r"^1[23456789]\d{9}$",
        help_text="移动电话号码，后台登录账号",
        validators=[UniqueValidator(queryset=AllinpayStaffList.objects.all())],
    )
    openid = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="openid",
    )
    unid = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="unionid",
    )
    code = CharField(
        help_text="短信校验码",
    )

    class Meta:
        fields = "__all__"


class WeChatAllinpayStaffListSerializer(serializers.ModelSerializer):
    """个人资料"""

    id = IntegerField(label="ID", read_only=True)
    nicename = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="昵称",
    )
    basename = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="真实姓名",
    )
    icon = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="头像",
    )
    phone = RegexField(
        r"^1[23456789]\d{9}$",
        help_text="移动电话号码，后台登录账号",
        validators=[UniqueValidator(queryset=AllinpayStaffList.objects.all())],
        read_only=True,
    )
    idcode = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="身份证号",
        validators=[UniqueValidator(queryset=AllinpayStaffList.objects.all())],
    )
    telent = CharField(
        allow_blank=True,
        allow_null=True,
        help_text="紧急联系人",
    )
    bankname = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="银行名称",
    )
    bankcard = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="银行卡号",
    )
    bankaddr = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="开户银行",
    )
    bankcode = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="银联行号",
    )
    created = ReadOnlyField()
    modifed = ReadOnlyField()
    status = ReadOnlyField()

    class Meta:
        model = AllinpayStaffList
        fields = [
            "id",
            "phone",
            "basename",
            "idcode",
            "telent",
            "nicename",
            "icon",
            "bankname",
            "bankcard",
            "bankaddr",
            "bankcode",
            "created",
            "modifed",
            "status",
        ]


class WeChatAllinpayPlaceListSerializer(serializers.ModelSerializer):
    """场所列表"""

    id = IntegerField(read_only=True)
    basename = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="简称",
    )
    name = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="全称",
    )
    addr = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="索引",
    )
    sheng = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False, help_text="省"
    )
    shi = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False, help_text="市"
    )
    xian = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False, help_text="县"
    )
    addre = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="详细地址",
    )
    shopcode = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="社会统一编码",
        validators=[UniqueValidator(queryset=AllinpayPlaceList.objects.all())],
    )
    licens = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="营业执照",
    )
    person = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="法人",
    )
    percode = RegexField(
        r"^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$",
        required=False,
        help_text="法人身份证",
    )
    phone = RegexField(r"^1[23456789]\d{9}$", required=False, help_text="法人联系电话")
    codea = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="法人身份证正面",
    )
    codeb = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="法人身份证背面",
    )
    titles = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="场所门头照片",
    )

    creattime = DateTimeField(read_only=True)
    status = IntegerField(read_only=True)
    telephone = CharField(read_only=True)
    auth = IntegerField(read_only=True)
    fee = CharField(read_only=True)

    Corp = SerializerMethodField()

    class Meta:
        model = AllinpayPlaceList
        fields = "__all__"

    def get_Corp(self, attr):
        try:
            sess = AllinpayPlacecorpList.objects.get(id=attr.auth)
        except BaseException as err:
            return {}
        return model_to_dict(sess)


# print(repr(WeChatAllinpayPlaceListSerializer()))


class WeChatAllinpayPlacestaffListSerializer(serializers.ModelSerializer):
    """我的场所列表"""

    id = IntegerField(label="ID", read_only=True)
    sid = IntegerField(required=True, help_text="员工ID")
    pid = IntegerField(required=True, help_text="场所ID")
    star = IntegerField(allow_null=True, required=False, help_text="星级")
    status = IntegerField(read_only=True)
    created = DateTimeField(read_only=True)
    modifed = DateTimeField(read_only=True)
    place = SerializerMethodField()
    staff = SerializerMethodField()
    role = SerializerMethodField()

    class Meta:
        model = AllinpayPlacestaffList
        fields = "__all__"

    def get_place(self, attr):
        try:
            sess = AllinpayPlaceList.objects.get(id=attr.pid)
        except BaseException as err:
            return {}
        return model_to_dict(sess)

    def get_staff(self, attr):
        try:
            sess = AllinpayStaffList.objects.get(id=attr.sid)
        except BaseException as err:
            return {}
        return model_to_dict(sess)

    def get_role(self, attr):
        sess = AllinpayPlacestaffRole.objects.filter(pid=attr.pid, sid=attr.sid)
        res = WeChatPlaceStaffRoleSerializer(sess, many=True)
        return res.data


class WeChatAllinpayPlacestaffActSerializer(serializers.ModelSerializer):
    """我的场所列表-审核"""

    status = IntegerField(required=True, help_text="状态")

    class Meta:
        model = AllinpayPlacestaffList
        fields = ["status"]


class WeChatPlaceStaffExtendSerializer(serializers.ModelSerializer):
    """场所员工扩展资料"""

    id = IntegerField(
        max_value=2147483647,
        min_value=-2147483648,
        validators=[UniqueValidator(queryset=AllinpayPlacestaffExtend.objects.all())],
    )
    metier = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="员工特长",
    )
    idcarda = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="身份证正面",
    )
    idcardb = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="身份证背面",
    )
    applya = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="入职申请A",
    )
    applyb = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="入职申请B",
    )
    contracta = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="劳动合同",
    )
    contractb = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="劳务合同",
    )
    mobile = IntegerField(
        allow_null=True,
        max_value=2147483647,
        min_value=-2147483648,
        required=False,
        help_text="移动端登录",
    )
    platform = IntegerField(
        allow_null=True,
        max_value=2147483647,
        min_value=-2147483648,
        required=False,
        help_text="场所端登录",
    )
    modifed = DateTimeField(read_only=True)

    basename = SerializerMethodField()

    class Meta:
        model = AllinpayPlacestaffExtend
        fields = "__all__"

    def get_basename(self, attr):
        try:
            sess = AllinpayPlacestaffList.objects.get(id=attr.id)
            res = AllinpayStaffList.objects.get(id=sess.sid)
        except BaseException as err:
            return ""
        return res.basename

    def to_representation(self, instance):
        # 改变序列化的输出
        data = super().to_representation(instance)
        # print("改变序列化的输出", instance, data)
        # if data["modifed"]:
        #     data["modifed"] = str(data["modifed"])
        return data


# print(repr(WeChatPlaceStaffExtendSerializer()))


class WeChatPlaceStaffRoleSerializer(serializers.ModelSerializer):
    """员工角色"""

    RoleName = SerializerMethodField()
    RolePers = SerializerMethodField()

    class Meta:
        model = AllinpayPlacestaffRole
        fields = "__all__"

    def get_RoleName(self, attr):
        try:
            sess = AllinpayPlaceroleList.objects.get(id=attr.rid)
        except BaseException as err:
            return {}
        return model_to_dict(sess)

    def get_RolePers(self, attr):
        sess = AllinpayPlacerolePerm.objects.filter(rid=attr.rid)
        res = WeChatPlaceRolePermSerializer(sess, many=True)
        return res.data


class WeChatPlaceRolePermSerializer(serializers.ModelSerializer):
    """角色权限"""

    PersName = SerializerMethodField()

    class Meta:
        model = AllinpayPlacerolePerm
        fields = "__all__"

    def get_PersName(self, attr):
        try:
            sess = AllinpayPlaceviewsList.objects.get(id=attr.vid)
        except BaseException as err:
            return {}
        return model_to_dict(sess)


class WeChatPlaceViewsListSerializer(serializers.ModelSerializer):
    """角色场所权限"""

    status = SerializerMethodField()

    class Meta:
        model = AllinpayAuthViews
        fields = "__all__"

    def get_status(self, attr):
        try:
            perm = AllinpayPlacerolePerm.objects.get(rid=attr.rid, vid=attr.id)
        except BaseException as err:
            return 0
        else:
            return perm.id


class WeChatAuthViewsListSerializer(serializers.ModelSerializer):
    """角色后台权限"""

    status = SerializerMethodField()

    class Meta:
        model = AllinpayAuthViews
        fields = "__all__"

    def get_status(self, attr):
        try:
            perm = AllinpayPlacerolePermYun.objects.get(rid=attr.rid, vid=attr.id)
        except BaseException as err:
            return 0
        else:
            return perm.id


class WeChatAllinpayPlaceRolePermSerializer(serializers.ModelSerializer):
    """角色场所权限"""

    id = IntegerField(label="ID", read_only=True)
    rid = IntegerField(required=True, help_text="角色ID")
    vid = IntegerField(required=True, help_text="权限ID")

    class Meta:
        model = AllinpayPlacerolePerm
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayPlacerolePerm.objects.all(), fields=("rid", "vid")
            )
        ]

    def validate_rid(self, attr):
        try:
            AllinpayPlaceroleList.objects.get(id=attr)
        except BaseException as err:
            raise serializers.ValidationError("角色对象不存在")
        return attr

    def validate_vid(self, attr):
        try:
            AllinpayPlaceviewsList.objects.get(id=attr)
        except BaseException as err:
            raise serializers.ValidationError("权限对象不存在")
        return attr


class WeChatAllinpayPlaceRolePermYunSerializer(serializers.ModelSerializer):
    """角色云端权限"""

    id = IntegerField(label="ID", read_only=True)
    rid = IntegerField(required=True, help_text="角色ID")
    vid = IntegerField(required=True, help_text="权限ID")

    class Meta:
        model = AllinpayPlacerolePermYun
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayPlacerolePermYun.objects.all(), fields=("rid", "vid")
            )
        ]

    def validate_rid(self, attr):
        try:
            AllinpayPlaceroleList.objects.get(id=attr)
        except BaseException as err:
            raise serializers.ValidationError("角色对象不存在")
        return attr

    def validate_vid(self, attr):
        try:
            AllinpayAuthViews.objects.get(id=attr)
        except BaseException as err:
            raise serializers.ValidationError("权限对象不存在")
        return attr


class WeChatAllinpayPlaceRoleListSerializer(serializers.ModelSerializer):
    """角色列表"""

    id = IntegerField(read_only=True)
    pid = IntegerField(required=True, help_text="场所ID")
    name = CharField(allow_blank=True, allow_null=True, required=True, help_text="角色名称")

    class Meta:
        model = AllinpayPlaceroleList
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayPlaceroleList.objects.all(), fields=("pid", "name")
            )
        ]


class WeChatAllinpayPlacestaffRoleSerializer(serializers.ModelSerializer):
    """员工分配角色"""

    id = IntegerField(read_only=True)
    pid = IntegerField(required=True, help_text="场所ID")
    sid = IntegerField(required=True, help_text="员工ID")
    rid = IntegerField(required=True, help_text="角色ID")
    placeName = SerializerMethodField()
    staffName = SerializerMethodField()
    roleName = SerializerMethodField()
    # bind = SerializerMethodField()

    class Meta:
        model = AllinpayPlacestaffRole
        fields = "__all__"

    def get_placeName(self, attr):
        try:
            r = AllinpayPlaceList.objects.get(id=attr.pid)
        except BaseException as err:
            return ""
        else:
            return r.name

    def get_staffName(self, attr):
        try:
            r = AllinpayStaffList.objects.get(id=attr.sid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def get_roleName(self, attr):
        try:
            r = AllinpayPlaceroleList.objects.get(id=attr.rid)
        except BaseException as err:
            return ""
        else:
            return r.name

    def get_bind(self, attr):
        return None


# =================================================================
class WeChatNewRolePlacePermsListSerializer(serializers.ListSerializer):
    """新角色场所权限分配列表"""

    def create(self, validated_data):
        books = []
        for item in validated_data:
            try:
                res = AllinpayPlaceroleList.objects.get(id=item.get("rid"))
            except BaseException as err:
                name = ""
            else:
                name = res.name
            try:
                instance = AllinpayPlacerolePerm.objects.get(
                    rid=item.get("rid"), vid=item.get("vid")
                )
                if not item.get("status") and not name == "管理员":
                    instance.delete()
            except BaseException as err:
                if item.get("status"):
                    instance = AllinpayPlacerolePerm(
                        rid=item.get("rid"), vid=item.get("vid")
                    )
                    instance.save()
                    books.append(instance)
        return books


class WeChatNewRolePlacePermsSerializer(serializers.Serializer):
    """新角色场所权限分配"""

    rid = IntegerField(help_text="角色ID")
    vid = IntegerField(help_text="权限ID")
    status = IntegerField(help_text="状态")

    class Meta:
        list_serializer_class = WeChatNewRolePlacePermsListSerializer
        fields = "__all__"


class WeChatNewRoleMobilePermsListSerializer(serializers.ListSerializer):
    """新角色云端权限分配列表"""

    def create(self, validated_data):
        books = []
        for item in validated_data:
            try:
                res = AllinpayPlaceroleList.objects.get(id=item.get("rid"))
            except BaseException as err:
                name = ""
            else:
                name = res.name
            try:
                instance = AllinpayPlacerolePermYun.objects.get(
                    rid=item.get("rid"), vid=item.get("vid")
                )
                if not item.get("status") and not name == "管理员":
                    instance.delete()
            except BaseException as err:
                if item.get("status"):
                    instance = AllinpayPlacerolePermYun(
                        rid=item.get("rid"), vid=item.get("vid")
                    )
                    instance.save()
                    books.append(instance)
        return books


class WeChatNewRoleMobilePermsSerializer(serializers.Serializer):
    """新角色云端权限分配"""

    rid = IntegerField(help_text="角色ID")
    vid = IntegerField(help_text="权限ID")
    status = IntegerField(help_text="状态")

    class Meta:
        list_serializer_class = WeChatNewRoleMobilePermsListSerializer
        fields = "__all__"


# ================================================================
# 呼叫部分
# ================================================================
class WeChatCallmeListSerializer(serializers.ModelSerializer):
    """呼叫列表"""

    # id = IntegerField(read_only=True)
    # reqsn = CharField(
    #     allow_blank=True,
    #     allow_null=True,
    #     required=False,
    #     help_text="呼叫订单号",
    #     validators=[UniqueValidator(queryset=AllinpayCallmeList.objects.all())],
    # )
    # rtype = CharField(
    #     allow_blank=True, allow_null=True, required=False, help_text="呼叫类型"
    # )
    # area = CharField(
    #     allow_blank=True, allow_null=True, required=False, help_text="区域(房号)"
    # )
    # source = CharField(
    #     allow_blank=True, allow_null=True, required=False, help_text="呼叫机号"
    # )
    # notes = CharField(allow_blank=True, allow_null=True, required=False, help_text="备注")
    # current = DateTimeField(allow_null=True, required=False, help_text="创建时间")
    # target = IntegerField(allow_null=True, required=False, help_text="呼叫目标ID")
    # timeout = IntegerField(allow_null=True, required=False, help_text="超时时间 (秒)")
    # overtime = IntegerField(allow_null=True, required=False, help_text="是否超时")
    # vipid = IntegerField(allow_null=True, required=False, help_text="会员ID")
    # status = IntegerField(allow_null=True, required=False, help_text="状态")
    # answer = IntegerField(allow_null=True, required=False, help_text="应答者ID")
    # antime = DateTimeField(allow_null=True, required=False, help_text="应答时间")
    # retime = DateTimeField(allow_null=True, required=False, help_text="接单时间")
    # complete = DateTimeField(allow_null=True, required=False, help_text="完成时间")
    # evaluate = DateTimeField(allow_null=True, required=False, help_text="评价时间")
    # star = CharField(allow_blank=True, allow_null=True, help_text="评价")
    # localid = IntegerField(allow_null=True, help_text="本地ID")
    # pid = IntegerField(allow_null=True, help_text="场所ID")

    class Meta:
        model = AllinpayCallmeList
        fields = "__all__"


# print(repr(WeChatAllinpayPlaceRoleListSerializer()))
